package com.easylinkin.linkappapi.function.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonAdminService;
import com.easylinkin.linkappapi.function.entity.FunctionRefPrivilege;
import com.easylinkin.linkappapi.function.entity.FunctionRefPrivilegeDTO;
import com.easylinkin.linkappapi.function.entity.FunctionRefTenant;
import com.easylinkin.linkappapi.function.entity.LinkappFunction;
import com.easylinkin.linkappapi.function.entity.LinkappFunctionRefDeviceType;
import com.easylinkin.linkappapi.function.mapper.LinkappFunctionMapper;
import com.easylinkin.linkappapi.function.mapper.LinkappFunctionRefDeviceTypeMapper;
import com.easylinkin.linkappapi.function.service.LinkappFunctionService;
import com.easylinkin.linkappapi.security.entity.LinkappPrivilege;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.entity.TenantRefPrivilege;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import java.util.List;
import java.util.UUID;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liuming
 * @since 2020-05-16
 */
@Service
public class LinkappFunctionServiceImpl extends ServiceImpl<LinkappFunctionMapper, LinkappFunction> implements LinkappFunctionService {

    @Resource
    private CommonAdminService commonAdminService;
    @Resource
    private LinkappFunctionMapper functionMapper;
    
    @Resource
    private LinkappTenantMapper tenantMapper;

    @Resource
    private LinkappFunctionRefDeviceTypeMapper linkappFunctionRefDeviceTypeMapper;
    
    private static final Logger LOGGER = LoggerFactory.getLogger(LinkappFunctionServiceImpl.class);


	/**
	 * 校验重复
	 */
	private void validRepeat(LinkappFunction linkappFunction) {
		QueryWrapper<LinkappFunction> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("identifier", linkappFunction.getIdentifier());
		List<LinkappFunction> list = baseMapper.selectList(queryWrapper);
		if (list.size() != 0) {
			if (list.size() > 1 || StringUtils.isEmpty(linkappFunction.getId()) || !linkappFunction.getId().equals(list.get(0).getId())) {
				throw new BusinessException("标识已存在");
			}
		}
		queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("function_name", linkappFunction.getFunctionName());
		list = baseMapper.selectList(queryWrapper);
		if (list.size() != 0) {
			if (list.size() > 1 || StringUtils.isEmpty(linkappFunction.getId()) || !linkappFunction.getId().equals(list.get(0).getId())) {
				throw new BusinessException("功能名称已存在");
			}
		}


	}


	/**
	 * 校验参数必填
	 */
	private void validParamRequired(LinkappFunction linkappFunction) {
		Assert.notNull(linkappFunction, "参数为空");
		Assert.isTrue(StringUtils.isNotBlank(linkappFunction.getFunctionName()), "名称为空");
		Assert.isTrue(linkappFunction.getType()!=null, "类型为空");
	}

	/**
	 * 校验参数格式
	 */
	private void validParamFormat(LinkappFunction linkappFunction) {
		Assert.isTrue(linkappFunction.getFunctionName() == null || linkappFunction.getFunctionName().length() <= 255, "名称超长");
		Assert.isTrue(linkappFunction.getDescription() == null || linkappFunction.getDescription().length() <= 1000, "描述超长");
		Assert.isTrue(linkappFunction.getIdentifier() == null || linkappFunction.getIdentifier().length() <= 50, "标识超长");
		Assert.isTrue(linkappFunction.getImgPath() == null || linkappFunction.getImgPath().length() <= 512, "预览图片地址超长");
	}
	

	@Override
	public boolean add(LinkappFunction function) {
		validParamRequired(function);
		validParamFormat(function);
		validRepeat(function);
		commonAdminService.setCreateAndModifyInfo(function);
		return this.save(function);
	}


	@Override
	public boolean updateLinkappFunction(LinkappFunction function) {
		Assert.notNull(function, "参数为空");
		Assert.hasLength(function.getId(), "参数id为空");
		LinkappFunction originLinkappFunction = getById(function.getId());
		Assert.notNull(originLinkappFunction, "原功能不存在");
		validRepeat(function);
		validParamFormat(function);
		commonAdminService.setCreateAndModifyInfo(function);
		return this.saveOrUpdate(function);
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteBatch(List<LinkappFunction> functions) {
		for(LinkappFunction function : functions) {
			functionMapper.deleteFunction2Privileges(function.getId());
			this.removeById(function.getId());
		}
		return true;
	}

	@Override
	public boolean delete(LinkappFunction function) {
		return this.removeById(function.getId());
	}


	@Override
	public List<LinkappFunction> getLinkappFunctions(LinkappFunction function) {
		return functionMapper.getLinkappFunctions(function);
	}


	@Override
	public IPage<LinkappFunction> getLinkappFunctionsPage(Page page, LinkappFunction function) {
		List<LinkappFunction> list = functionMapper.getLinkappFunctions(page, function);
		return page.setRecords(list);
	}

	@Override
	public LinkappFunction getLinkappFunction(LinkappFunction function) {
		return functionMapper.getLinkappFunction(function);
	}

	@Override
	public List<LinkappPrivilege> selectPrivilegeByFunction(String id) {
		return functionMapper.selectPrivilegeByFunction(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void function2Privileges(FunctionRefPrivilegeDTO functionRefPrivilegeDTO) {
		LinkappFunction function = functionRefPrivilegeDTO.getFunction();
		function = functionMapper.selectById(function);
		List<LinkappPrivilege> privileges = functionRefPrivilegeDTO.getPrivileges();
		functionMapper.deleteFunction2Privileges(function.getId());
		for(LinkappPrivilege privilege :privileges) {
			FunctionRefPrivilege functionRefPrivilege = new FunctionRefPrivilege();
			functionRefPrivilege.setFunctionId(function.getId());
			functionRefPrivilege.setPrivilegeId(privilege.getId().toString());
			functionRefPrivilege.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			functionMapper.insertFunction2Privileges(functionRefPrivilege);
		}
		List<LinkappTenant> tenants = functionMapper.selectTenantByFunction(function.getId());
		if(!tenants.isEmpty()) {
			for(LinkappTenant tenant : tenants ) {
				for(LinkappPrivilege privilege:privileges) {
					TenantRefPrivilege tenantRefPrivilege = new TenantRefPrivilege();
					tenantRefPrivilege.setId(UUID.randomUUID().toString().replaceAll("-", ""));
					tenantRefPrivilege.setTenantId(tenant.getId());
					tenantRefPrivilege.setPrivilegeId(privilege.getId()+"");
					tenantMapper.insertTenant2Privileges(tenantRefPrivilege);
				}
			}
		}
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void functions2Tenant(String tenantId,List<LinkappFunction> functions) {
		functionMapper.deleteFunctions2Tenant(tenantId);
		for(LinkappFunction function :functions) {
			FunctionRefTenant functionRefTenant = new FunctionRefTenant();
			functionRefTenant.setFunctionId(function.getId());
			functionRefTenant.setTenantId(tenantId);
			functionRefTenant.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			functionMapper.insertFunctions2Tenant(functionRefTenant);
		}
	}

	@Override
	public LinkappFunctionRefDeviceType getRefDeviceType(String functionId) {
		return linkappFunctionRefDeviceTypeMapper.findByfunctionId(functionId);
	}

	@Override
	public Object saveOrUpdateDeviceType(LinkappFunctionRefDeviceType functionRefDeviceType) {
		//查询已存在的绑定关系
		LinkappFunctionRefDeviceType refDeviceType = linkappFunctionRefDeviceTypeMapper
				.findByfunctionId(functionRefDeviceType.getFunctionId());
		//如果存在，则进行修改
		if(refDeviceType!=null){
			refDeviceType.setRefDeviceTypeList(functionRefDeviceType.getRefDeviceTypeList());
			linkappFunctionRefDeviceTypeMapper.updateById(refDeviceType);
		}else{
			refDeviceType = new LinkappFunctionRefDeviceType();
			refDeviceType.setFunctionId(functionRefDeviceType.getFunctionId());
			refDeviceType.setRefDeviceTypeList(functionRefDeviceType.getRefDeviceTypeList());
			linkappFunctionRefDeviceTypeMapper.insert(refDeviceType);
		}
		return null;
	}
}
